import { useRouter } from "next/router"; import { GenerationLatencyChart } from "@/src/features/dashboard/components/LatencyChart"; import { ChartScores } from "@/src/features/dashboard/components/ChartScores"; import { TracesBarListChart } from "@/src/features/dashboard/components/TracesBarListChart"; import { ModelCostTable } from "@/src/features/dashboard/components/ModelCostTable"; import { ScoresTable } from "@/src/features/dashboard/components/ScoresTable"; import { ModelUsageChart } from "@/src/features/dashboard/components/ModelUsageChart"; import { TracesAndObservationsTimeSeriesChart } from "@/src/features/dashboard/components/TracesTimeSeriesChart"; import { UserChart } from "@/src/features/dashboard/components/UserChart"; import { TimeRangePicker } from "@/src/components/date-picker"; import { api } from "@/src/utils/api"; import { FeedbackButtonWrapper } from "@/src/features/feedback/component/FeedbackButton"; import { BarChart2 } from "lucide-react"; import { Button } from "@/src/components/ui/button"; import { PopoverFilterBuilder } from "@/src/features/filters/components/filter-builder"; import { type FilterState } from "@langfuse/shared"; import { type ColumnDefinition } from "@langfuse/shared"; import { useQueryFilterState } from "@/src/features/filters/hooks/useFilterState"; import { LatencyTables } from "@/src/features/dashboard/components/LatencyTables"; import { useMemo } from "react"; import { findClosestDashboardInterval, DASHBOARD_AGGREGATION_OPTIONS, toAbsoluteTimeRange, type DashboardDateRangeAggregationOption, } from "@/src/utils/date-range-utils"; import { useDashboardDateRange } from "@/src/hooks/useDashboardDateRange"; import { useDebounce } from "@/src/hooks/useDebounce"; import { ScoreAnalytics } from "@/src/features/dashboard/components/score-analytics/ScoreAnalytics"; import SetupTracingButton from "@/src/features/setup/components/SetupTracingButton"; import { useUiCustomization } from "@/src/ee/features/ui-customization/useUiCustomization"; import { useEntitlementLimit } from "@/src/features/entitlements/hooks"; import Page from "@/src/components/layouts/page"; import { MultiSelect } from "@/src/features/filters/components/multi-select"; import { convertSelectedEnvironmentsToFilter, useEnvironmentFilter, } from "@/src/hooks/use-environment-filter"; export default function Dashboard() { const router = useRouter(); const projectId = router.query.projectId as string; const { timeRange, setTimeRange } = useDashboardDateRange(); const absoluteTimeRange = useMemo( () => toAbsoluteTimeRange(timeRange), [timeRange], ); const uiCustomization = useUiCustomization(); const lookbackLimit = useEntitlementLimit("data-access-days"); const [userFilterState, setUserFilterState] = useQueryFilterState( [], "dashboard", projectId, ); const traceFilterOptions = api.traces.filterOptions.useQuery( { projectId, }, { trpc: { context: { skipBatch: true, }, }, refetchOnMount: false, refetchOnWindowFocus: false, refetchOnReconnect: false, staleTime: Infinity, }, ); const environmentFilterOptions = api.projects.environmentFilterOptions.useQuery( { projectId, fromTimestamp: absoluteTimeRange?.from, }, { trpc: { context: { skipBatch: true, }, }, refetchOnMount: false, refetchOnWindowFocus: false, refetchOnReconnect: false, staleTime: Infinity, }, ); const environmentOptions: string[] = environmentFilterOptions.data?.map((value) => value.environment) || []; // Add effect to update filter state when environments change const { selectedEnvironments, setSelectedEnvironments } = useEnvironmentFilter(environmentOptions, projectId); const nameOptions = traceFilterOptions.data?.name?.map((n) => ({ value: n.value, count: Number(n.count), })) || []; const tagsOptions = traceFilterOptions.data?.tags || []; const filterColumns: ColumnDefinition[] = [ { name: "Trace Name", id: "traceName", type: "stringOptions", options: nameOptions, internal: "internalValue", }, { name: "Tags", id: "tags", type: "arrayOptions", options: tagsOptions, internal: "internalValue", }, { name: "User", id: "user", type: "string", internal: "internalValue", }, { name: "Release", id: "release", type: "string", internal: "internalValue", }, { name: "Version", id: "version", type: "string", internal: "internalValue", }, ]; const dashboardTimeRangePresets = DASHBOARD_AGGREGATION_OPTIONS; const agg = useMemo(() => { if ("range" in timeRange) { return timeRange.range as DashboardDateRangeAggregationOption; } return findClosestDashboardInterval(timeRange) ?? "last7Days"; }, [timeRange]); const fromTimestamp = absoluteTimeRange?.from ? absoluteTimeRange.from : new Date(new Date().getTime() - 1000); const toTimestamp = absoluteTimeRange?.to ? absoluteTimeRange.to : new Date(); const timeFilter = [ { type: "datetime" as const, column: "startTime", operator: ">" as const, value: fromTimestamp, }, { type: "datetime" as const, column: "startTime", operator: "<" as const, value: toTimestamp, }, ]; const environmentFilter = convertSelectedEnvironmentsToFilter( ["environment"], selectedEnvironments, ); const mergedFilterState: FilterState = [ ...userFilterState, ...timeFilter, ...environmentFilter, ]; return ( ({ value: env, }))} className="my-0 w-auto overflow-hidden" /> ), actionButtonsRight: ( <> {uiCustomization?.feedbackHref === undefined && ( )} ), }} >
); }